package com.jyy.prefabricated.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jyy.prefabricated.common.AjaxResult;
import com.jyy.prefabricated.dto.OrderDto;
import com.jyy.prefabricated.dto.OrderListDto;
import com.jyy.prefabricated.dto.Pageable;
import com.jyy.prefabricated.entity.OrderInfo;
import com.jyy.prefabricated.entity.SysUser;
import com.jyy.prefabricated.enums.OrderTypeEnum;
import com.jyy.prefabricated.enums.UserTypeEnum;
import com.jyy.prefabricated.service.OrderInfoService;
import com.jyy.prefabricated.utils.ExcelUtil;
import com.jyy.prefabricated.utils.UserUtils;
import junit.framework.Test;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 订单
 *
 * @version 1.0.0
 * @author: zjj
 */
@Slf4j
@RequestMapping("/api")
@RestController
public class OrderInfoController {

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private UserUtils userUtils;

    /**
     * 新增订单
     *
     * @param dto
     * @return
     */
    @PostMapping("/orders")
    public AjaxResult insert(@Valid @RequestBody OrderDto dto) {
        log.info("Rest request to insert orderInfo:{}", dto);
        OrderInfo result = orderInfoService.createOrder(dto);
        return AjaxResult.success(result);
    }

    /**
     * 新增订单（管理员）
     *
     * @param dto
     * @return
     */
    @PostMapping("/orders-admin")
    public AjaxResult adminInsert(@Valid @RequestBody OrderListDto dto) {
        log.info("Rest request to insert orderInfo:{}", dto);
        orderInfoService.adminCreateOrder(dto);
        return AjaxResult.success();
    }

    /**
     * 新增订单(对公转账订单)
     *
     * @param dto
     * @return
     */
    @PostMapping("/public_transfer_orders")
    public AjaxResult insertOrder(@Valid @RequestBody OrderDto dto) {
        log.info("Rest request to insert orderInfo:{}", dto);
        OrderInfo result = orderInfoService.createPublicTransferOrder(dto);
        return AjaxResult.success(result);
    }

    /**
     * 审核订单(对公转账订单)
     *
     * @param orderInfo
     * @return
     */
    @PutMapping("/orders_status")
    public AjaxResult updateStatus(@Valid @RequestBody OrderInfo orderInfo) {
        log.info("Rest request to update orderInfo:{}", orderInfo);
        orderInfoService.updateStatus(orderInfo);
        OrderInfo result = orderInfoService.selectById(orderInfo.getId());
        return AjaxResult.success(result);
    }

    /**
     * 修改订单
     *
     * @param orderInfo
     * @return
     */
    @PutMapping("/orders")
    public AjaxResult update(@Valid @RequestBody OrderInfo orderInfo) {
        log.info("Rest request to update orderInfo:{}", orderInfo);
        orderInfoService.update(orderInfo);
        OrderInfo result = orderInfoService.selectById(orderInfo.getId());
        return AjaxResult.success(result);
    }

    /**
     * 查询订单详情
     *
     * @param id
     * @return
     */
    @GetMapping("/orders/{id}")
    public AjaxResult selectById(@PathVariable Integer id) {
        log.info("Rest request to find orderInfo by id:{}", id);
        OrderInfo result = orderInfoService.selectById(id);
        return AjaxResult.success(result);
    }


    /**
     * 查询订单列表
     *
     * @param productName 产品名称
     * @param orderType   订单类型
     * @param orderStatus 订单状态
     * @param pageable    分页信息
     * @param startDate   支付起始时间
     * @param endDate    支付结束时间
     * @return
     */
    @GetMapping("/orders")
    public AjaxResult selectByParams(@RequestParam(required = false, defaultValue = "") String productName, @RequestParam(required = false) Integer orderType, @RequestParam(required = false) Integer orderStatus, @RequestParam(required = false, defaultValue = "") String startDate, @RequestParam(required = false, defaultValue = "") String endDate, Pageable pageable) {
        log.info("Rest request to find orderInfo by productName:{},orderType:{},orderStatus:{}", productName, orderType, orderStatus);
        SysUser user = userUtils.getCurrentUser();
        PageHelper.startPage(pageable.getPageNum(), pageable.getPageSize());
        List<OrderInfo> orderInfos = new ArrayList<>();
        if (UserTypeEnum.ADMIN.getValue().equals(user.getUserType())) {
            orderInfos = orderInfoService.selectByParams(productName, orderType, null, orderStatus, startDate, endDate);
        } else {
            orderInfos = orderInfoService.selectByParams(productName, orderType, user.getId(), orderStatus, startDate, endDate);
        }

        PageInfo<OrderInfo> result = new PageInfo<>(orderInfos);
        return AjaxResult.success(result);
    }

    /**
     * 订单导出
     *
     * @param
     * @return
     */
    @GetMapping("/orders-excel")
    public void downloadRecordExcel(@RequestParam(required = false, defaultValue = "") String productName, @RequestParam(required = false) Integer orderType, @RequestParam(required = false) Integer orderStatus,  @RequestParam(required = false, defaultValue = "") String startDate, @RequestParam(required = false, defaultValue = "") String endDate, HttpServletResponse response) {
        SysUser user = userUtils.getCurrentUser();
        List<OrderInfo> orderInfos = new ArrayList<>();
        if (UserTypeEnum.ADMIN.getValue().equals(user.getUserType())) {
            orderInfos = orderInfoService.selectByParams(productName, orderType, null, orderStatus, startDate, endDate);
            downloadExcel(orderInfos, response);
        } else {
            orderInfos = orderInfoService.selectByParams(productName, orderType, user.getId(), orderStatus, startDate, endDate);
            downloadExcel(orderInfos, response);
        }
        return;
    }

    /**
     * 导出excel
     *
     * @param list
     * @param response
     */
    public void downloadExcel(List<OrderInfo> list, HttpServletResponse response) {
        String title = "订单列表";
        Workbook workbook = writeDataToExcel(list);
        try {
            ExcelUtil.downloadExcel(response, workbook, title);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将数据写入excel
     *
     * @param list
     * @return
     */
    public Workbook writeDataToExcel(List<OrderInfo> list) {
        String[] titleList = {"订单编号", "名称", "分类", "售价", "订单分类", "数量", "购买人", "支付时间"};
        InputStream is = Test.class.getClassLoader().getResourceAsStream("templates/order.xlsx");
        //检查模板文件
        Workbook workbook = null;
        try {
            workbook = new XSSFWorkbook(is);
            if (workbook != null) {
                for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
                    //获得当前sheet工作表
                    Sheet sheet = workbook.getSheetAt(sheetNum);
                    if (sheet == null) {
                        continue;
                    }
                    //获得当前sheet的结束行
                    int lastRowNum = sheet.getLastRowNum();
                    Row firstRow = sheet.getRow(lastRowNum - 1);
                    int columnNum = 0;
                    if (firstRow != null) {
                        columnNum = firstRow.getPhysicalNumberOfCells();
                    }
                    for (int j = 0; j < columnNum; j++) {
                        Cell cell = firstRow.getCell(j); //第1行,第j列
                        String cellValue = cell.getStringCellValue();
                        System.out.println(cellValue);
                    }
                    Row row = sheet.createRow(lastRowNum + 1);
                    //创建内容
                    Cell dataCell = null;
                    Long count = 0L;
                    for (int i = 0; i < list.size(); i++) {
                        row = sheet.createRow(lastRowNum + i + 1);
                        for (int j = 0; j < titleList.length; j++) {
                            dataCell = row.createCell(j);
                            if (j == 0) {
                                String value = list.get(i).getOrderCode();
                                dataFormat(dataCell, value);
                            } else if (j == 1) {
                                String value = list.get(i).getProductName();
                                dataFormat(dataCell, value);
                            } else if (j == 2) {
                                String value = list.get(i).getProductCategory();
                                dataFormat(dataCell, value);
                            } else if (j == 3) {
                                long value = list.get(i).getPrice().longValue();
                                dataFormat(dataCell, value);
                            } else if (j == 4) {
                                Integer value = list.get(i).getOrderType();
                                if (value.equals(OrderTypeEnum.COURSE.getValue())) {
                                    dataFormat(dataCell, OrderTypeEnum.COURSE.getLabel());
                                } else if (value.equals(OrderTypeEnum.COURSE_PACKAGE.getValue())) {
                                    dataFormat(dataCell, OrderTypeEnum.COURSE_PACKAGE.getLabel());
                                } else if (value.equals(OrderTypeEnum.PROJECT.getValue())) {
                                    dataFormat(dataCell, OrderTypeEnum.PROJECT.getLabel());
                                } else if (value.equals(OrderTypeEnum.Practice.getValue())) {
                                    dataFormat(dataCell, OrderTypeEnum.Practice.getLabel());
                                } else if (value.equals(OrderTypeEnum.Exam.getValue())) {
                                    dataFormat(dataCell, OrderTypeEnum.Exam.getLabel());
                                } else if (value.equals(OrderTypeEnum.QuestionBank.getValue())) {
                                    dataFormat(dataCell, OrderTypeEnum.QuestionBank.getLabel());
                                }

                            } else if (j == 5) {
                                Integer value = list.get(i).getQuantity();
                                dataFormat(dataCell, value);
                            } else if (j == 6) {
                                String value = list.get(i).getBuyerName();
                                dataFormat(dataCell, value);
                            } else if (j == 7) {
                                String value = list.get(i).getPayTime();
                                dataFormat(dataCell, value);
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return workbook;
    }

    /**
     * 单元格值格式化
     *
     * @param dataCell
     * @param obj
     */
    private static void dataFormat(Cell dataCell, Object obj) {
        if (obj == null) {
            dataCell.setCellValue("");
        } else {
            if (obj instanceof String) {
                dataCell.setCellValue((String) obj);
            } else if (obj instanceof Double) {
                dataCell.setCellValue((Double) obj);
            } else if (obj instanceof Float) {
                dataCell.setCellValue((Float) obj);
            } else if (obj instanceof Long) {
                dataCell.setCellValue((Long) obj);
            } else if (obj instanceof Integer) {
                dataCell.setCellValue((Integer) obj);
            } else if (obj instanceof Boolean) {
                dataCell.setCellValue((Boolean) obj);
            } else if (obj instanceof Date) {
                Date d = (Date) obj;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String createDate = sdf.format(d);
                dataCell.setCellValue(createDate);
            }
        }
    }

}
